package com.kf.controller;



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kf.aop.LogOperation;
import com.kf.config.AliyunOSSUtil;
import com.kf.config.RedisUtil;
import com.kf.config.SecurityUser;


import com.kf.mapper.NoticefileMapper;
import com.kf.pojo.Notice;
import com.kf.pojo.Noticefile;

import com.kf.pojo.User;

import com.kf.pojo.WenFile;
import com.kf.pojo.form.*;
import com.kf.service.*;

import com.kf.util.MD5Utils;

import com.kf.util.R;
import com.kf.util.RandomUtil;
import com.kf.util.ResultCode;
import io.swagger.annotations.ApiOperation;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 常见控制器
 *
 * @author Honey
 * @date 2022/12/23
 */
@RestController
@RequestMapping("/common")
public class CommonController {
    @Resource
    UserService userService;


    @Resource
    NoticeService noticeService;
    @Resource
    NoticeRepository noticeRepository;
    @Resource
    CommonService commonService;
    @Resource
    NoticefileService noticefileService;
    @Resource
    RedisUtil redisUtil;
    @Resource
    AliyunOSSUtil aliyunOSSUtil;
    @Resource
    NoticefileMapper noticefileMapper;

    private final Logger logger= LoggerFactory.getLogger(this.getClass());

    @PostMapping("/update/password")
    @ApiOperation("修改密码")
    @LogOperation("修改密码")
    public R updatePassword(@Validated(UserForm.Login.class)  @RequestBody UserForm userForm){
        User user = SecurityUser.getUser();
        User user1 = userService.queryUserByName(userForm.getUsername());
        if(user1==null){
            return R.error(ResultCode.LOGIN_ERROR);
        }
        if(!user1.getPhone().equals(userForm.getPhone())){
            return R.error(ResultCode.LOGIN_ERROR1);
        }
        String encrypt = MD5Utils.encrypt(user.getUsername(), userForm.getPassword());
        user.setPassword(encrypt);
        userService.updatePassword(user);
        return R.okey(ResultCode.SUCCESS_UPDATE_PWD);

    }


    @PostMapping("/notices")
    @ApiOperation("新增公告")
    @LogOperation("新增公告")
    public R addNotice(@Validated @RequestBody AddNotice addNotice)  {

        User user = SecurityUser.getUser();
        noticeService.insertNotice(addNotice,user);
        return R.ok();
    }

    @GetMapping("/notice/{id}/info")
    @ApiOperation("拿到具体公告")
    public R addNotice(@PathVariable("id") String id)  {

        try {
            Notice notice  = noticeService.getNoticeById(id);
            QueryWrapper<Noticefile> noticefileQueryWrapper = new QueryWrapper<>();
            noticefileQueryWrapper.eq("notice_id",notice.getId());
            List<Noticefile> noticefiles = noticefileMapper.selectList(noticefileQueryWrapper);
            NoticeFileForm noticeFileForm = new NoticeFileForm();
            noticeFileForm.setNotice(notice);
            noticeFileForm.setNoticefiles(noticefiles);
            return R.ok().put("data",noticeFileForm);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(ResultCode.FAIL);
        }

    }
    @PostMapping("/update/notices")
    @ApiOperation("修改公告")
    @Transactional(rollbackFor = Exception.class)
    @LogOperation("修改公告")
    public R updateNotice(@Validated @RequestParam("files") List<MultipartFile> files,
                          @RequestParam("noticeId")int noticeId,
//                          @RequestParam("id")List<Integer> list,
                          @RequestParam("target")int target,
                          @RequestParam("noticeTopic")String noticeTopic,
                          @RequestParam("noticeContent")String noticeContent)  {
        try {
            User user = SecurityUser.getUser();
            AddNotice addNotice = new AddNotice();
            addNotice.setNoticeTopic(noticeTopic).setNoticeContent(noticeContent).setTarget(target).setId(String.valueOf(noticeId));
            noticeService.updateNotice(addNotice,user);

            for (MultipartFile file : files) {
                String filename = file.getOriginalFilename();
                System.out.println(filename + "==filename");
                ResourceBundle resource = ResourceBundle.getBundle("oss");
                String noticeurl = resource.getString("noticeurl");

                assert filename != null;
                String[] split =new String[2];
                split[0]= filename.substring(0,filename.lastIndexOf("."));
                split[1] = filename.substring(filename.lastIndexOf(".")+1,
                        filename.length());

                String fileCode = aliyunOSSUtil.getFileCode();
                if(AliyunOSSUtil.TXT.equals(split[1])|| AliyunOSSUtil.DOCX.equals(split[1])|| AliyunOSSUtil.PDF.equals(split[1])|| AliyunOSSUtil.DOC.equals(split[1])|| AliyunOSSUtil.XLS.equals(split[1])) {
                    System.out.println("类型正确");
                    if (!"".equals(filename.trim())) {
                        Noticefile noticefile  = new Noticefile();
                        noticefileService.updateNoticeFile(noticefile,user,split,noticeId,fileCode);
                        // 上传到OSS
                        aliyunOSSUtil.upLoad3(file, noticeurl,fileCode,split[1]);
                    }
                }else{
                    return R.error(ResultCode.USER_UPFILE_ERROR);
                }
            }
        } catch (Exception e) {
            return R.error(ResultCode.FAIL);
        }
        return R.ok();
    }

    @PostMapping("/delete/notices")
    @ApiOperation("删除")
    @LogOperation("删除公告")
    @Transactional(rollbackFor = Exception.class)
    public R deleteNotice(@Validated @RequestBody DeleteForm deleteForm)  {

        try {
            noticeService.deleteNotice(deleteForm);
        } catch (Exception e) {
            return R.error(ResultCode.FAIL);
        }
        return R.ok();
    }
    @PostMapping("/delete/{id}/noticefile")
    @ApiOperation("删除公告文件")
    @LogOperation("删除公告文件")
    @Transactional(rollbackFor = Exception.class)
    public R deleteNoticeFile(@Validated @PathVariable int id)  {

        try {
            noticefileService.deleteFile(id);
        } catch (Exception e) {
            return R.error(ResultCode.FAIL);
        }
        return R.ok();
    }
    @GetMapping("/all/notices")
    @ApiOperation("拿到公告信息")
    public R getAllNotice() throws IOException {
        User user = SecurityUser.getUser();
        List<Notice> allNotice = commonService.getAllNotice(user);

        return R.ok().put("data",allNotice);
    }
    @GetMapping("/all/notices/perms")
    @ApiOperation("拿到公告信息")
    public R getAllNotices() throws IOException {
        User user = SecurityUser.getUser();
        List<Notice> allNotice = commonService.getAllNotice(user);

        return R.ok().put("data",allNotice);
    }

    @GetMapping("send/{phone}")
    public R sendMsm(@PathVariable String phone) throws Exception {

        String code  = RandomUtil.getSixBitRandom();
        Map<String,Object> param = new HashMap<>();
        param.put("code",code);
//        if(redisUtil.hasKey(phone)){
//            return  R.ok();
//        }
        boolean isSend = commonService.send(param,phone);
        if(isSend) {
            redisUtil.set(phone,code,5*60);
            return R.ok();
        } else {
            return R.error("短信发送失败");
        }
    }

    @PostMapping("/noticefile")
    @ApiOperation("上传公告文件")
    @Transactional(rollbackFor = Exception.class)
    @LogOperation("上传公告文件")
    public R commitPaper(@RequestParam("files") List<MultipartFile> files,
             @RequestParam("target")int target,
             @RequestParam("noticeTopic")String noticeTopic,
             @RequestParam("noticeContent")String noticeContent)  {
        User user = SecurityUser.getUser();
        AddNotice addNotice = new AddNotice();
        addNotice.setNoticeTopic(noticeTopic).setNoticeContent(noticeContent).setTarget(target);
        int noticeId = noticeService.insertNotice(addNotice, user);
        for (MultipartFile file : files) {
            String filename = file.getOriginalFilename();
            System.out.println(filename + "==filename");
            ResourceBundle resource = ResourceBundle.getBundle("oss");
            String noticeurl = resource.getString("noticeurl");
            String[] split =new String[2];
            split[0]= filename.substring(0,filename.lastIndexOf("."));
            split[1] = filename.substring(filename.lastIndexOf(".")+1,
                    filename.length());

            String fileCode = aliyunOSSUtil.getFileCode();
            if(AliyunOSSUtil.TXT.equals(split[1])|| AliyunOSSUtil.DOCX.equals(split[1])|| AliyunOSSUtil.PDF.equals(split[1])|| AliyunOSSUtil.DOC.equals(split[1])|| AliyunOSSUtil.XLS.equals(split[1])){
                System.out.println("类型正确");
                if (!"".equals(filename.trim())) {
                    aliyunOSSUtil.upLoad3(file, noticeurl,fileCode,split[1]);
                    Noticefile noticefile  = new Noticefile();
                    noticefileService.insertNoticeFile(noticefile,user,split,noticeId,fileCode);
                }
            }else{
                return R.error(ResultCode.USER_UPFILE_ERROR);
            }
        }

        return R.okey(ResultCode.SUCCESS);
    }

    @PostMapping("/down/notice")
    @LogOperation("下载公告")
    @ApiOperation("下载公告")
    public R downWenxian(@NotNull @RequestParam("id")int id, HttpServletResponse response)  {
        try {


            Noticefile noticefile = noticefileService.getById(id);
            if(noticefile!=null){
                //文件路径
                String path=noticefile.getPath()+"/"+noticefile.getFilecode()+"."+ noticefile.getSuffix();
                response.addHeader("Content-Disposition", "attachment;filename=" +new String((noticefile.getFilename()+"."+ noticefile.getSuffix()).getBytes("UTF-8"),"ISO-8859-1"));
                aliyunOSSUtil.exportOssFile(response.getOutputStream(),path);
            }
            return R.okey(ResultCode.SUCCESS);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error(ResultCode.FAIL);
        }
    }
    @GetMapping("check/{username}")
    public R checkUsername(@PathVariable String username)  {
        User user = userService.queryUserByName(username);
        if(user==null) {
            return R.error(ResultCode.LOGIN_ERROR);
        }
        String phone = user.getPhone();
        return R.okey(ResultCode.SUCCESS).put("data",phone);
    }

    @GetMapping("/esnotice")
    public  SearchHits<Notice>  getEsNotice(String keyword)  {
        SearchHits<Notice> titleOrDesc = noticeRepository.findTitle(keyword);
        return titleOrDesc;
    }
    @GetMapping("/esnotice1")
    public R   getEsNotice1(String keyword)  {
        ArrayList<Notice> list = new ArrayList<>();
        User user = SecurityUser.getUser();
        System.out.println("getnotice"+keyword);
        SearchHits<Notice> titleOrDesc = noticeRepository.findTitleOrDesc(keyword);
        for (SearchHit<Notice> noticeSearchHit : titleOrDesc) {
            Map<String, List<String>> highlightFields = noticeSearchHit.getHighlightFields();
            List<String> createby = highlightFields.get("createby");
            if(createby!=null){
                noticeSearchHit.getContent().setCreateby(createby.toString().substring(1,createby.toString().length()-1));
            }
            List<String> noticeTopic = highlightFields.get("noticeTopic");
            if(noticeTopic!=null){
                noticeSearchHit.getContent().setNoticeTopic(noticeTopic.toString().substring(1,noticeTopic.toString().length()-1));
            }
            List<String> noticeContent = highlightFields.get("noticeContent");
            if(noticeContent!=null){
                noticeSearchHit.getContent().setNoticeContent(noticeContent.toString().substring(1,noticeContent.toString().length()-1));
            }
            list.add(noticeSearchHit.getContent());

        }
        List<Notice> studentNotice = list.stream().filter(x ->
                x.getTarget() == 1||x.getTarget()==0).collect(Collectors.toList());

        if(user.getState()==1){
            studentNotice.sort(Comparator.comparing(Notice::getHeat));
            Collections.reverse(studentNotice);
            return R.okey(ResultCode.SUCCESS).put("data",studentNotice);
        }else {
            list.sort(Comparator.comparing(Notice::getHeat));
            Collections.reverse(list);
            return R.okey(ResultCode.SUCCESS).put("data",list);
        }


    }



    @GetMapping("/esnotice2")
    public R   getEsNotice2(String keyword)  {
        SearchHits<Notice> titleOrDesc = noticeRepository.findTitleOrDesc1(keyword);
        return R.okey(ResultCode.SUCCESS).put("data",titleOrDesc);

    }


    @PostMapping("/notice/info")
    public R getNoticeInfo(String msg){
        System.out.println(msg);
        logger.info(msg);
        return R.ok().put("data",msg);
    }

}

